package com.wandian.robot;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.PropertyConfigurator;
import com.wandian.action.LoginAction;
import com.wandian.action.RobotAction;
import com.wandian.executor.Action;
import com.wandian.executor.DelayAction;
import com.wandian.executor.Executor;
import com.wandian.executor.TimerMgr;
import com.wandian.texas.DataPacket;
import com.wandian.texas.GameData;
import com.wandian.texas.protocol.Protocol;
import com.wandian.util.Config;
import com.wandian.util.DateUtil;
import com.wandian.util.Log;
import com.wandian.util.PathUtil;

/**
 * @author long
 * @Create 2012-11-13 下午2:58:47
 * @QQ 108232706
 * @version 1.0
 * @description RobotMgr
 */
public class RobotMgr {
	// private static HashMap<Integer, Robot> robotMap;
	private static List<Robot> robots = new ArrayList<Robot>();
	private static HashMap<String, Robot> robotMap = new HashMap<String, Robot>();
	private static Executor executor;
	private static ThreadPoolExecutor pool;
	public static Selector selector = null;
	public static ReentrantLock selectorLock = new ReentrantLock();
	public static boolean isService = false;
	public static final Map<Short, String> cmdSocket = new HashMap<Short, String>();

	public static AtomicInteger curRegisterRobot = new AtomicInteger();
	private static Thread serviceThread;
	public static String GameserverIp;
	public static int GameserverPort;
	private static String robotPrefix;
	public static String robotPassword;
	public static int robotBegin;
	public static int robotStartRoomId;
	private static int robotCount = 100;

	public static void incrementRobot() {
		Log.debug("===========注册了robot个数========" + RobotMgr.curRegisterRobot.incrementAndGet());
		if (RobotMgr.curRegisterRobot.get() >= robotCount) {
			Log.info("============机器人开始登陆");
			isService = true;
			serviceThread = new Thread(new Runnable() {
				public void run() {
					service();
				}
			}, "Robot-Service");
			serviceThread.start();
			new Thread(new Runnable() {
				public void run() {
					MainProcess();
				}
			}, "Robot-MainProcess").start();
			Robot robot;
			for (int i = 0; i < robots.size(); i++) {
				robot = robots.get(i);
				run(new RobotAction(robot) {
					@Override
					public void run() {
						synchronized (robot.dataPacket) {
							robot.setCmd(Protocol.UserLoginCmd);
							robot.writeBegin();
							robot.writeByte((byte) 0);
							robot.writeString(robot.username);
							robot.writeString(RobotMgr.robotPassword);
							robot.writeInt(1);
							robot.writeEnd();
							robot.SendData();
						}
					}
				});
				try {
					TimeUnit.MICROSECONDS.sleep(50);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
	}

	public static void main(String[] args) {
		GameData.CONFIGPATH = PathUtil.getAasolutePath(args[0]);// String.format("%s/%s",
		if (!Config.initConfig(GameData.CONFIGPATH)) {
			System.out.println("系统配置文件加载错误，程序退出!");
			return;
		} else {
			PropertyConfigurator.configure(PathUtil.getAasolutePath(Config.getValue("log4j.path")));
			Log.debug("加载配置文件成功");
		}
		GameserverIp = Config.getValue("robot.ip");
		GameserverPort = Integer.valueOf(Config.getValue("robot.port"));
		robotPrefix = Config.getValue("robot.prefix");
		robotPassword = Config.getValue("robot.password");
		robotBegin = Integer.valueOf(Config.getValue("robot.begin"));
		robotCount = Integer.valueOf(Config.getValue("robot.count"));
		robotStartRoomId = Integer.valueOf(Config.getValue("robot.startRoomId"));
		corePoolSize = Integer.valueOf(Config.getValue("robot.corePoolSize"));
		maxPoolSize = Integer.valueOf(Config.getValue("robot.maxPoolSize"));
		timerPoolSize = Integer.valueOf(Config.getValue("robot.timerPoolSize"));
		if (robotStartRoomId < 1)
			robotStartRoomId = 1;
		Log.info(String.format("[CenterServer]机器人启动中.........."));
		cmdStart();
		String mycmd;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			while (true) {
				try {
					mycmd = br.readLine();
					if ("exit".equals(mycmd)) {
						stop();
						break;
					} else if ("startup".equals(mycmd)) {
						cmdStart();
					} else if ("robots".equals(mycmd)) {
						printRobots();
					} else if (mycmd.startsWith("see")) {
						try {
							String username = mycmd.substring(3);
							Robot rb = robotMap.get(username);
							Log.info(rb == null ? "null" : rb.getInfo());
						} catch (Exception e) {
						}
					} else {
						Log.info(String.format("[] 命令不支持!"));
					}
				} catch (Exception e) {
					e.printStackTrace();
					Log.info(String.format("[GameServer][%s] 运行异常%s!", DateUtil.format(new Date()), e));
					break;
				}
				TimeUnit.MILLISECONDS.sleep(1);
			}// end while
			br.close();
		} catch (InterruptedException e) {
			Log.info(String.format("[GameServer][%s] 运行中出现异常:%s!", DateUtil.format(new Date()), e));
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("exit app");
	}

	public static void cmdStart() {
		RobotMgr.init();
		RobotMgr.startRobot();
	}

	public static void close(Robot robot) {
		if (robots.contains(robot)) {
			robots.remove(robot);
		}
		robot.close();
	}

	static int corePoolSize = 4;
	static int maxPoolSize = 8;
	static int timerPoolSize = 5;

	public static boolean init() {
		initCommand();
		// robotMap = new HashMap<Integer, Robot>();
		// int corePoolSize = 8;
		// int maxPoolSize = 16;
		// int keepAliveTime = 5;
		// int cacheSize = 64;

		int keepAliveTime = 5;
		//		int cacheSize = 3;
		TimeUnit unit = TimeUnit.MINUTES;
		ThreadFactory threadFactory = new Threads("Robot");
		RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
		pool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, new LinkedBlockingQueue<Runnable>(), threadFactory, handler);
		// executor = new Executor(corePoolSize, maxPoolSize, keepAliveTime,
		// cacheSize, "Robot");
		// robotCount = _robotCount;
		try {
			if (selector != null) {
				selector.close();
			}
			selector = null;
			selector = Selector.open();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// executor.enDelayQueue(new
		// MatchStartAction(executor.getDefaultQueue(),
		// System.currentTimeMillis(), 20000));
		return true;
	}

	private static void initCommand() {
		cmdSocket.put((short) 1000, "UserLoginCmd");
		cmdSocket.put((short) 2004, "FastEnterRoomCmd");
		cmdSocket.put((short) 3998, "LobbyCmd");
		cmdSocket.put((short) 3999, "GameRoomCmd");
		cmdSocket.put((short) 4000, "EnterRoomCmd");
		cmdSocket.put((short) 4001, "RoomInfoCmd");
		cmdSocket.put((short) 4002, "SitdownCmd");
		cmdSocket.put((short) 4003, "InGAameRoomCmd");
		cmdSocket.put((short) 4004, "OutGameRoomCmd");
		cmdSocket.put((short) 4005, "StandUpCmd");
		cmdSocket.put((short) 4006, "StartGameCmd");
		cmdSocket.put((short) 4007, "CMD_GameMessageList");
		cmdSocket.put((short) 4008, "CMD_SETROOMINFO");
		cmdSocket.put((short) 4009, "CMD_PLAYERS");

		cmdSocket.put((short) 4010, "CMD_REQUESTINFOMATION");
		cmdSocket.put((short) 4011, "CMD_ROOMINFOUPDATE");
		cmdSocket.put((short) 4012, "CMD_ROOMPLAYERNUMCHANGE");
		cmdSocket.put((short) 4013, "CMD_OPERATION_NEXT");
		cmdSocket.put((short) 4014, "CMD_OPERATION_REQUEST");
		cmdSocket.put((short) 4015, "CMD_OPERATION_SUCC");
		cmdSocket.put((short) 4016, "CMD_CUR_POT");
		cmdSocket.put((short) 4017, "CMD_POTS");
		cmdSocket.put((short) 4018, "CMD_SNAPCARDS_FLOP");
		cmdSocket.put((short) 4019, "CMD_SNAPCARDS_TURN");
		cmdSocket.put((short) 4020, "CMD_SNAPCARDS_RIVER");
		cmdSocket.put((short) 4021, "CMD_SHOW");

		cmdSocket.put((short) 5000, "CMD_GAME_OVER");

		cmdSocket.put((short) 10003, "CMD_GAME_ROOM_SOCKET_CLOSE");
	}

	public static boolean stop() {
		Log.info("the RobotMgr is stop...");
		isService = false;
		try {
			if (!pool.awaitTermination(3, TimeUnit.SECONDS)) {
				System.out.println("not run over");
				pool.shutdownNow();
				// pool.shutdown();
			} else {
				System.out.println(" run over");
				pool.shutdownNow();
			}
			TimerMgr.awaitTermination(2);
			TimerMgr.shutdownNow();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		for (int i = 0; i < robots.size(); i++) {
			robots.get(i).close();
		}
		serviceThread.interrupt();
		return true;
	}

	public static void MainProcess() {
		Robot robot;
		while (isService) {
			try {
				for (int i = 0; i < robots.size(); i++) {
					try {
						robot = robots.get(i);
						if (robot.connected) {
							if (getPacketData(robot)) {
								OnCommand(robot);
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
				TimeUnit.MILLISECONDS.sleep(1);
			} catch (InterruptedException e) {
				System.out.println("取包服务停止interrupted");
				Thread.currentThread().interrupt();
			}
		}
	}

	// static int count=0;
	public static void OnCommand(Robot robot) {
//		 Log.info("OnCommand " + cmdSocket.get(robot.getRecCmd())+".position:"+robot.recDataPacket.position()+"limit:"+robot.recDataPacket.limit());
		switch (robot.getRecCmd()) {
		case Protocol.UserLoginCmd:
//			robot.StatusList.append("UserLoginCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseLogin();
				}
			});
			break;
		case Protocol.RoomListCmd: {
			// count++;
			// Log.info("收到房间列表个数:"+count);
//			robot.StatusList.append("RoomListCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseRoomList();
				}
			});
		}
			break;
		case Protocol.FastEnterRoomCmd: {
//			robot.StatusList.append("FastEnterRoomCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseFastEnterRoomData();
				}
			});
		}
			break;
		case Protocol.CMD_REGISTER: {
//			robot.StatusList.append("CMD_REGISTER|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseRegister();
				}
			});
		}
			break;
		case Protocol.CMD_PLAYERS: {
			//			robot.StatusList.append("CMD_PLAYERS|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseRoomPlayer();
				}
			});
		}
			break;
		case Protocol.RoomInfoCmd: {
			//			robot.StatusList.append("RoomInfoCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseRoomInfoCmd();
				}
			});
		}
			break;
		// 房间当前状态??
		case Protocol.InGAameRoomCmd: {
			//			robot.StatusList.append("InGAameRoomCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseInGAameRoomCmd();
				}
			});
		}
			break;
		case Protocol.SitdownCmd: {
			//			robot.StatusList.append("SitdownCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseSitdown();
				}
			});
		}
			break;
		case Protocol.CMD_SETROOMINFO: {
			//			robot.StatusList.append("setroom|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseSetRoomInfo();
				}
			});
		}
			break;
		case Protocol.CMD_ROOMINFOUPDATE: {
			//			robot.StatusList.append("roomchange|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_ROOMINFOUPDATE();
				}
			});
		}
			break;
		case Protocol.CMD_ROOMPLAYERNUMCHANGE: {
			//			robot.StatusList.append("roomnumchange|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_ROOMPLAYERNUMCHANGE();
				}
			});
		}
			break;
		case Protocol.StartGameCmd: {
			//			robot.StatusList.append("StartGameCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseStartGame();
				}
			});
		}
			break;
		case Protocol.CMD_OPERATION_NEXT: {
			//			robot.StatusList.append("CMD_OPERATION_NEXT|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.responseCMD_OPERATION_NEXT();
				}
			});
		}
			break;
		case Protocol.CMD_OPERATION_SUCC: {
			//			robot.StatusList.append("CMD_OPERATION_SUCC|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_OPERATION_SUCC();
				}
			});
		}
			break;
		case Protocol.CMD_SNAPCARDS_FLOP: {
			//			robot.StatusList.append("CMD_SNAPCARDS_FLOP|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_SNAPCARDS_FLOP();
				}
			});
		}
			break;
		case Protocol.CMD_SNAPCARDS_TURN: {
			//			robot.StatusList.append("CMD_SNAPCARDS_TURN|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_SNAPCARDS_TURN();
				}
			});
		}
			break;
		case Protocol.CMD_SNAPCARDS_RIVER: {
			//			robot.StatusList.append("CMD_SNAPCARDS_RIVER|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_SNAPCARDS_RIVER();
				}
			});
		}
			break;
		case Protocol.CMD_CUR_POT: {
			//			robot.StatusList.append("CMD_CUR_POT|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_CUR_POT();
				}
			});
		}
			break;
		case Protocol.CMD_SHOW: {
			//			robot.StatusList.append("CMD_SHOW|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_SHOW();
				}
			});
		}
			break;
		case Protocol.CMD_POTS: {
			//			robot.StatusList.append("CMD_POTS|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_POTS();
				}
			});
		}
			break;
		case Protocol.CMD_GAME_OVER: {
			//			robot.StatusList.append("CMD_GAME_OVER|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_GAME_OVER();
				}
			});
		}
			break;
		case Protocol.StandUpCmd: {
			//			robot.StatusList.append("StandUpCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.StandUpCmd();
				}
			});
		}
			break;
		case Protocol.OutGameRoomCmd: {
			//			robot.StatusList.append("OutGameRoomCmd|");
			run(new RobotAction(robot) {
				@Override
				public void run() {
					robot.CMD_OUT_GAME_ROOM();
				}
			});
		}
			break;
		default:
			robot.readEnd();
			break;
		}
	}

	/**
	 * 提取一个包
	 * 
	 * @param sessionObj
	 * @return
	 */
	private static boolean getPacketData(Robot robot) {
		// 相当于fireMessageReceived接受到，只是这里是读写线程之外的线程操作
		if (!robot.getHasReceiveData().get()) {
			return false;
		}
		if (robot.isUseRecDataPacket) {
			return false;
		}
		robot.isUseRecDataPacket = true;
		boolean remain = false;
		ByteBuffer recvBuffer = robot.RecvBuffer;
		synchronized (recvBuffer) {
			// 长度不够
			if (recvBuffer.position() < 22) {
				robot.isUseRecDataPacket = false;
				return false;
			}
			int oldposition = recvBuffer.position();
			recvBuffer.flip();
			//			int remainLength = recvBuffer.remaining();
			int head = recvBuffer.getInt();
			if (head != 29099) {
				recvBuffer.position(0);
				recvBuffer.clear();// 本包出现问题，清空缓冲区，也可以断线处理
				printByteBufferInfo("[SessionMgr]本包出现问题 getPacketData>> RecvBuffer", recvBuffer);
				robot.isUseRecDataPacket = false;
				throw new IllegalArgumentException("head not 29099");
//				return false;
			}
			int lenght = recvBuffer.getInt();
			// 粘包,头4个字节正确，只是包长度没有发完，只有继续等
			if (lenght > recvBuffer.remaining() + 8) {
				recvBuffer.position(oldposition);
				recvBuffer.limit(recvBuffer.capacity());
				printByteBufferInfo("[SessionMgr]包长度没有发完 getPacketData>> RecvBuffer", recvBuffer);
				robot.isUseRecDataPacket = false;
				return false;
			}
			DataPacket dataPacket = robot.recDataPacket;
			dataPacket.cmdId = recvBuffer.getShort();
			recvBuffer.position(22);
			dataPacket.writeBegin();
			lenght -= 22;
			while (lenght > 0) {
				dataPacket.writeByte(recvBuffer.get());
				lenght--;
			}
			dataPacket.writeEnd();
			// printByteBufferInfo("<<getPacketData RecvBuffer", recvBuffer);
			// 提取数据操作

			// recvBuffer.position(22);
			// byte[] bytes = new byte[lenght - 22];
			// // 将数据部分提取
			// recvBuffer.get(bytes, 0, bytes.length);
			// // dataPacket.writeBegin();
			// dataPacket.writeBytes(bytes);// 将包数据部分存入ByteBuffer
			// dataPacket.writeEnd();
			// Log.debug(String.format("[RobotMgr]接收到数据包,=====in==========in=========>命令:%s %s 总长度:%s 数据:%s",
			// dataPacket.cmdId, cmdSocket.get(dataPacket.cmdId), lenght,
			// dataPacket.byteToHex()));
			if (recvBuffer.remaining() > 0) {
				remain = true;
			}
			recvBuffer.compact();// 清除处理过的数据
			// 因为compact已经将
			// position恢复到limit,等待接收数据,limit到最大
			// recvBuffer.position(remainLength - lenght);
			// recvBuffer.limit(recvBuffer.capacity());
		}
		robot.setHasReceiveData(remain);// 在下个取包操作时候，标志位,无包可以省去很多开销
		return true;
	}

	static final long SELECT_TIMEOUT = 1000L;

	public static void service() {
		int n;
		Log.debug("===========开始侦听服务========");
		while (!Thread.currentThread().isInterrupted() && isService) {
			try {
				n = selector.select(SELECT_TIMEOUT);
				if (n > 0) {
					Set<SelectionKey> readyKeys = selector.selectedKeys();
					Iterator<SelectionKey> it = readyKeys.iterator();
					while (it.hasNext()) {
						SelectionKey key = null;
						try {
							key = it.next();
							it.remove();
							if (key.isReadable()) {
								receive(key);
							}
							// if (key.isWritable())
							// {
							// send(key);
							// }
						} catch (IOException e) {
							e.printStackTrace();
							closeSessionKey(key);
						}
					}
				}
				TimeUnit.MILLISECONDS.sleep(1);

			} catch (IOException e1) {
				Log.error(String.format("[service]acceptor select() error%s ,break out", e1));
				Thread.currentThread().interrupt();
				break;
			} catch (InterruptedException e) {
				System.out.println("监听器服务停止interrupted");
				Thread.currentThread().interrupt();
			}
		}

	}

	public static void send(SelectionKey key) throws IOException {
		Robot robot = (Robot) key.attachment();
		if (!robot.getHasSendData().get()) {
			return;
		}
		synchronized (robot.SendBuffer) {
			robot.SendBuffer.flip(); // 把极限设为位置，把位置设为零
			robot.socketChannel.write(robot.SendBuffer); // 发送数据，写的时候覆盖了之前的数据，
			// 一个完整包长度不够，设置没有数据
			if (robot.SendBuffer.remaining() <= 0) {
				robot.setHasSendData(false);
			}
			robot.SendBuffer.compact(); // 删除已经发送的数据
		}
	}

	private static void printByteBufferInfo(String msg, ByteBuffer tempBuffer) {
		Log.info(String.format("%s remaining:%s position:%s limit:%s", msg, tempBuffer.remaining(), tempBuffer.position(), tempBuffer.limit()));
	}

	public static boolean receive(SelectionKey key) throws IOException {
		Robot robot = (Robot) key.attachment();
		SocketChannel socketChannel = (SocketChannel) key.channel();
		// 接收数据，可以从key中获得
		int num = 0;
		ByteBuffer tempBuffer = robot.RecvBuffer;
		synchronized (tempBuffer) {
			num = socketChannel.read(tempBuffer);
			if (tempBuffer.position() > 0) {
				// printByteBufferInfo(robot + "接收数据后 RecvBuffer", tempBuffer);
				robot.setHasReceiveData(true);
			}
		}
		if (num == -1) {
			closeSessionKey(key);
			return false;
			// throw new IOException("user have close!");
		}
		return true;
	}

	private static void closeSessionKey(SelectionKey key) {
		// 如果发生异常，取消该事件
		try {
			// 如果发生异常，取消该事件
			if (key != null) {
				Robot robot = (Robot) key.attachment();
				robot.connected = false;
				key.cancel();
			}
		} catch (Exception ex) {
			Log.info(ex);
		}

	}

	public static void run(Runnable action) {
		try {
			pool.execute(action);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void startRobot() {
		Robot robot;
		for (int i = RobotMgr.robotBegin; i < RobotMgr.robotCount + RobotMgr.robotBegin; i++) {
			robot = new Robot(RobotMgr.robotPrefix + i, i);
			// robotMap.put(i, robot);
			robots.add(robot);
			robotMap.put(robot.username, robot);
			// run(new LoginAction(robots.get(i)));
			// enDefaultQueue(new LoginAction(robot));
			run(new LoginAction(robot));
		}
		System.out.println("机器人初始化完毕");
		TimerMgr.init(timerPoolSize);
	}

	public static Executor getExeccutor() {
		return executor;
	}

	public static void enDefaultQueue(Action action) {
		executor.enDefaultQueue(action);
	}

	public static void enDelayQueue(DelayAction action) {
		executor.enDelayQueue(action);
	}

	public static void printRobots() {
		Robot robot;
		StringBuilder sb = new StringBuilder("机器人总数：" + robots.size() + " ");
		for (int i = 0; i < robots.size(); i++) {
			robot = robots.get(i);
			sb.append(robot.getInfo() + "\r\n");
		}
		Log.info(sb.toString());
	}

	static class Threads implements ThreadFactory {
		static final AtomicInteger poolNumber = new AtomicInteger(1);
		final ThreadGroup group;
		final AtomicInteger threadNumber = new AtomicInteger(1);
		final String namePrefix;

		public Thread newThread(Runnable runnable) {
			Thread thread = new Thread(this.group, runnable, this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
			if (thread.isDaemon())
				thread.setDaemon(false);
			if (thread.getPriority() != 5)
				thread.setPriority(5);
			return thread;
		}

		Threads(String prefix) {
			SecurityManager securitymanager = System.getSecurityManager();
			this.group = (securitymanager == null ? Thread.currentThread().getThreadGroup() : securitymanager.getThreadGroup());
			this.namePrefix = ("pool-" + poolNumber.getAndIncrement() + "-" + prefix + "-thread-");
		}
	}
}
